package com.dawn.module.hospital.service;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.dawn.framework.common.exception.ServerException;
import com.dawn.framework.common.pojo.CommonResult;
import com.dawn.framework.common.util.http.HttpUtils;
import com.dawn.framework.common.util.json.JsonUtils;
import com.dawn.framework.web.core.util.WebFrameworkUtils;
import com.dawn.module.hospital.controller.app.outpatient.vo.*;
import com.dawn.module.hospital.enums.BHConstants;
import com.dawn.module.hospital.enums.ErrorCodeConstants;
import com.dawn.module.hospital.util.DateUtils;
import com.dawn.module.hospital.util.RandomUtils;
import com.dawn.module.hospital.util.SecEncryptUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * @description:
 * @author: cnsu-cmh
 * @time: 2024/8/7 15:49
 */
@Slf4j
@Service
public class OutpatientService extends BHService {

    @Autowired
    private PatientService patientService;

    @Autowired
    private TemplateMsgService templateMsgService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private EhealthService ehealthService;

    @Autowired
    private EInvoiceService eInvoiceService;

    @Autowired
    private RefundService refundService;

    public CommonResult registerList(OutpatientRegisterQueryReqVO reqVO) {
        Map params = new HashMap();
        String traceId = WebFrameworkUtils.getTraceId();
        params.put("traceId",traceId);
        params.put("hisProvider", BHConstants.HIS_PROVIDER);
        params.put("patientId", reqVO.getPatientId());
        params.put("days", 7);
        params.put("payTypeID", BHConstants.PAY_CARD_WX_HIS);
        CommonResult apiResult = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_OUTPATIENT_REGISTER_LIST.getValue(), params);
        log.info("registerList PAY_CARD_WX_HIS apiResult:" + JSONUtil.toJsonStr(apiResult));


        Map map = new HashMap();
        if (apiResult.isSuccess()) {
            List<Map> ghList = getRegisterList(apiResult);
            if (ghList != null && ghList.size() > 0) {
                map.put("ghList", ghList);
                String data = JSONObject.toJSONString(apiResult.getData());
                Base64.Encoder encoder = Base64.getEncoder();
                String dataText = null;
                try {
                    dataText = encoder.encodeToString(data.getBytes("utf-8"));
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
//                map.put("dataText", dataText);
                apiResult = CommonResult.success(map);
            } else {
                apiResult = CommonResult.error(ERROR_CODE, "未获取到缴费挂号单");
            }
            return apiResult;
        } else {
            return apiResult;
        }

    }

    /**
     * 获取缴费挂号单信息
     *
     * @param result
     * @return
     */
    public List<Map> getRegisterList(CommonResult result){
        List<Map> ghList = new ArrayList<>();
        Map dataMap = (Map) result.getData();
        if(!StringUtils.isEmpty(dataMap)){
            List<Map> mapList = (List<Map>) dataMap.get("GHLIST");
            if(!StringUtils.isEmpty(mapList)) {
                for (Map ghMap : mapList) {
                    //挂号就诊列表
                    List<Map>  gList = (List<Map>) ghMap.get("GH");
                    if(!StringUtils.isEmpty(gList)){
                        for (Map map : gList) {
                            String no = String.valueOf(map.get("NO"));
                            Map m = getRegisterRecipe(result,null,no);
                            List<Map> djList = (List<Map>) m.get("djList");
                            if(djList.size()>0){
                                ghList.add(map);
                            }
                        }
                    }
                }
            }
        }
        return ghList;
    }

    /**
     * 获取缴费单据信息
     *
     * @param result
     * @return
     */
    public Map getRegisterRecipe(CommonResult result, String data, String registerNo)  {
        Map resultMap = new HashMap();

        List<Map> newYzMapList =new ArrayList<>();
        List<Map> newDjMapList =new ArrayList<>();
        List<Map> newFmMapList =new ArrayList<>();
        String dataText = "";
        Map dataMap = new HashMap();
        if(StringUtils.hasLength(data)){
            Base64.Decoder decoder = Base64.getDecoder();
            String newEncodeStr = data.replaceAll(" ", "+");
            String dataJson = null;
            try {
                dataJson = new String(decoder.decode(newEncodeStr),"utf-8");
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
            dataMap = JSONUtil.toBean(dataJson,Map.class);
        }else {
            dataMap = (Map) result.getData();
        }

        List<Map> mapList = (List<Map>) dataMap.get("GHLIST");
        if(!StringUtils.isEmpty(mapList)) {
            for (Map ghMap : mapList) {
                //挂号就诊列表
                List<Map> ghList = (List<Map>) ghMap.get("GH");
                for (Map gh : ghList) {
                    String djh = String.valueOf(gh.get("NO"));
                    if (registerNo.equals(djh)) {
                        List<Map> yzMapList = (List<Map>) gh.get("YZLIST");
                        if (!StringUtils.isEmpty(yzMapList)) {
                            for (Map yzMap : yzMapList) {
                                List<Map> yzList = (List<Map>) yzMap.get("YZ");
                                for (Map y : yzList) {
                                    y.put("registerNo", registerNo);
                                    List<Map> djListMap = (List<Map>) y.get("DJLIST");
                                    String YZLX = String.valueOf(y.get("YZLX"));
                                    String YZID = String.valueOf(y.get("YZID"));
                                    String YZMC = String.valueOf(y.get("YZMC"));

                                    int yzAdd = 0;
                                    String djhStr = "";
                                    if (!StringUtils.isEmpty(djListMap)) {
                                        for (Map djMap : djListMap) {
                                            List<Map> djList = (List<Map>) djMap.get("DJ");
                                            for (Map dj : djList) {
                                                String zfzt = String.valueOf(dj.get("ZFZT"));
                                                String dj_djh = String.valueOf(dj.get("DJH"));
                                                dj.put("registerNo", registerNo);
                                                dj.put("YZLX", YZLX);
                                                dj.put("YZID", YZID);
                                                dj.put("YZMC", YZMC);

                                                if ("0".equals(zfzt)) {
                                                    yzAdd += 1;
                                                    djhStr += dj_djh + ",";
                                                    boolean r = true;
                                                    for (Map m : newDjMapList) {
                                                        String feeItemId = String.valueOf(m.get("DJH"));
                                                        if (dj_djh.equals(feeItemId)) {
                                                            r = false;
                                                        }
                                                    }
                                                    if (!r) {
                                                        continue;
                                                    }
                                                    newDjMapList.add(dj);
                                                }
                                            }
                                        }
                                    }
                                    if (yzAdd > 0) {
                                        djhStr = djhStr.substring(0, djhStr.length() - 1);
                                        y.put("DJH", djhStr);
                                        newYzMapList.add(y);

                                        List<Map> fmListMap = (List<Map>) y.get("FMLIST");
                                        if (!StringUtils.isEmpty(fmListMap)) {
                                            for (Map fmMap : fmListMap) {
                                                List<Map> fmList = (List<Map>) fmMap.get("FM");
                                                for (Map fm : fmList) {
                                                    fm.put("registerNo", registerNo);
                                                    fm.put("YZLX", YZLX);
                                                    fm.put("YZID", YZID);
                                                    fm.put("YZMC", YZMC);
                                                    fm.put("DJH", djhStr);
                                                    newFmMapList.add(fm);
                                                }
                                            }
                                        }
                                    }
                                }
                                Base64.Encoder encoder = Base64.getEncoder();
                                try {
                                    dataText = encoder.encodeToString(JSONObject.toJSONString(yzList).getBytes("utf-8"));
                                } catch (UnsupportedEncodingException e) {
                                    e.printStackTrace();
                                }
                            }
                        }

                        String ghzfzt = String.valueOf(gh.get("ZFZT"));
                        if ("0".equals(ghzfzt)) {
                            HashMap<String, Object> ghDjMap = new HashMap();
                            ghDjMap.put("registerNo", registerNo);
                            ghDjMap.put("YZLX", String.valueOf(gh.get("LX")));
                            ghDjMap.put("YZID", "25000325697");
                            ghDjMap.put("YZMC", "挂号费");
                            ghDjMap.put("JE", gh.get("JE"));
                            ghDjMap.put("DJH", gh.get("NO"));
                            ghDjMap.put("KDSJ", gh.get("YYSJ"));
                            ghDjMap.put("ZFZT", gh.get("ZFZT"));
                            newDjMapList.add(ghDjMap);
                        }
                    }
                }
            }
        }
        //医嘱信息
        resultMap.put("yzList", newYzMapList);
        //单据信息
        resultMap.put("djList", newDjMapList);
        //费目信息
        resultMap.put("fmList", newFmMapList);
        //单据信息
        resultMap.put("dataText", dataText);
        return resultMap;
    }

    public CommonResult unPayList(OutpatientUnpayQueryReqVO reqVO) {
        Map params = new HashMap();
        String traceId = WebFrameworkUtils.getTraceId();
        params.put("traceId",traceId);
        params.put("hisProvider", BHConstants.HIS_PROVIDER);
        params.put("patientId",reqVO.getPatientId());
        params.put("days",7);

        params.put("payTypeID", BHConstants.PAY_CARD_WX_HIS);

        CommonResult apiResult = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_OUTPATIENT_REGISTER_LIST.getValue(), params);
        log.info("registerList PAY_CARD_WX_HIS apiResult:"+JSONUtil.toJsonStr(apiResult));
//        Map resultMap = (Map) apiResult.getData();
//        if(resultMap!=null && resultMap.isEmpty()){
//            params.put("payTypeID", BHConstants.PAY_CARD_ALI_HIS);
//            apiResult = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_OUTPATIENT_REGISTER_LIST.getValue(), params);
//            log.info("registerList PAY_CARD_ALI_HIS apiResult:"+JSONUtil.toJsonStr(apiResult));
//        }

        Map map = new HashMap();
        if(apiResult.isSuccess()){
            List<Map> ghList = getRegisterList(apiResult);
            if(ghList!=null && ghList.size()>0){
                map.put("ghList", ghList);
                String data = JSONObject.toJSONString(apiResult.getData());
                Base64.Encoder encoder = Base64.getEncoder();
                try {
                    String dataText = encoder.encodeToString(data.getBytes("utf-8"));
                    reqVO.setDataText(dataText);
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
        }else {
            return apiResult;
        }



        Map dataMap = new HashMap();
        dataMap.put("registerNo", reqVO.getRegisterNo());

        Map recipeMap = getRegisterRecipe(apiResult,reqVO.getDataText(),reqVO.getRegisterNo());

        //医嘱信息
        dataMap.put("yzList", recipeMap.get("yzList"));
        //单据信息
        dataMap.put("djList", recipeMap.get("djList"));
        //单据信息
//        dataMap.put("dataText", recipeMap.get("dataText"));
        //费目信息
        dataMap.put("fmList", recipeMap.get("fmList"));

        dataMap.put("chs_pay", true);

        return CommonResult.success(dataMap);
    }

    public CommonResult orderItems(OutpatientUnpayQueryReqVO reqVO) {
        Map params = new HashMap();
        String traceId = WebFrameworkUtils.getTraceId();
        params.put("traceId",traceId);
        params.put("hisProvider", BHConstants.HIS_PROVIDER);
        params.put("tradeSerialNumber", RandomUtil.randomNumbers(9));
        params.put("patientId",reqVO.getPatientId());
        params.put("registerNo",reqVO.getRegisterNo());

        return HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_OUTPATIENT_ITEM_LIST.getValue(), params);
    }

    public CommonResult createOrder(OutpatientCreateOrderReqVO reqVO) {
        if(!StringUtils.hasText(reqVO.getOrderType())) {
            reqVO.setOrderType("收费单");
        }

        Map params = createBillOrderParams(reqVO);

//        String payType = reqVO.getPayType();
        String orderType = reqVO.getOrderType();
        String totalCost = reqVO.getTotalCost();
        String registerNo = reqVO.getRegisterNo();

        BigDecimal totalCostB = new BigDecimal(totalCost);
        BigDecimal totalAmountB = new BigDecimal(0);

        Map outpatientMap = new HashMap();
        String orderName = "门诊缴费";
        String orderNumber;

        JSONObject orderDetails = new JSONObject();
        orderDetails.put("patientName", reqVO.getPatientName());
        orderDetails.put("patientId", reqVO.getPatientId());
        orderDetails.put("cardNo", reqVO.getCardNo());
        orderDetails.put("clinicNo", reqVO.getClinicNo());
        orderDetails.put("userId", reqVO.getUserId());
        orderDetails.put("openid", reqVO.getOpenid());
        orderDetails.put("pid", reqVO.getPId());
        orderDetails.put("registerNo", reqVO.getRegisterNo());
        orderDetails.put("receiptNoStr", reqVO.getReceiptNoStr());

        if(StringUtils.hasLength(orderType) && "nat".equals(orderType)) {
            String feeType = reqVO.getFeeType();
            String feeId = reqVO.getFeeId();
            String feeItem = reqVO.getFeeItem();

            if (StringUtils.isEmpty(feeType)) {
                return CommonResult.error(ERROR_CODE,"费用类别不能为空");
            }
            if (StringUtils.isEmpty(feeId)) {
                return CommonResult.error(ERROR_CODE,"费用项目ID不能为空");
            }
            if (StringUtils.isEmpty(feeItem)) {
                return CommonResult.error(ERROR_CODE,"用项目不能为空");
            }

            String natDeptName = configApi.getConfigValueByKey(BHConstants.NAT_DEPT_NAME.getValue());
            String natDoctorName = configApi.getConfigValueByKey(BHConstants.NAT_DOCTOR_NAME.getValue());
            String natHm = configApi.getConfigValueByKey(BHConstants.NAT_HM.getValue());

            if (StringUtils.isEmpty(natDeptName) || StringUtils.isEmpty(natDoctorName) || StringUtils.isEmpty(natHm)) {
                return CommonResult.error(ERROR_CODE,"请检查核酸开单配置数据");
            }
            orderName = "核酸检测";
            orderNumber = "NAT" + RandomUtils.buildRandomStr(4);
            params.put("orderNumber",orderNumber);
            params.put("tradeSerialNumber",orderNumber);

            totalAmountB = new BigDecimal(totalCost);

            List<Map> outpatients = new ArrayList<>();
            Map outpatient_nat = new HashMap(params);
            outpatient_nat.put("userId",reqVO.getUserId());
            outpatient_nat.put("patientId",reqVO.getPatientId());
            outpatient_nat.put("patientName", reqVO.getPatientName());
            outpatient_nat.put("cardNo", reqVO.getCardNo());
            outpatient_nat.put("idCardNo",reqVO.getCardNo());
            outpatient_nat.put("clinicNo",reqVO.getClinicNo());

            outpatient_nat.put("registerNo",registerNo);
            outpatient_nat.put("fee",totalCost);
            outpatient_nat.put("amount",totalCost);
            outpatient_nat.put("presDate", DateUtils.getDateTime());
            outpatient_nat.put("departmentName", natDeptName);
            outpatient_nat.put("doctorName",natDoctorName);
            outpatient_nat.put("doctorId",natHm);
            outpatient_nat.put("cost",totalCost);
            outpatient_nat.put("regTime", DateUtils.getDateTime());

            outpatient_nat.put("feeType",feeType);
            outpatient_nat.put("feeId",feeId);
            outpatient_nat.put("feeItem",feeItem);

            outpatient_nat.put("feeItemId",feeId);
            outpatient_nat.put("feeItemType",feeType);

            outpatient_nat.put("totalFee",totalCost);
            outpatient_nat.put("sumfee",totalCost);
            outpatient_nat.put("status","0");
            outpatient_nat.put("regType",orderType);

            outpatients.add(outpatient_nat);
            outpatientMap.put("prescriptions", JSONObject.toJSONString(outpatients));
            outpatientMap.put("prices","");
            orderDetails.put("prescriptions",outpatients);
        } else {
            Map arg = new HashMap();
            String traceId = WebFrameworkUtils.getTraceId();
            params.put("traceId",traceId);
            arg.put("hisProvider", BHConstants.HIS_PROVIDER);
            arg.put("patientId",reqVO.getPatientId());
            arg.put("days",7);
            arg.put("payTypeID", BHConstants.PAY_CARD_WX_HIS);

            CommonResult apiResult = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_OUTPATIENT_REGISTER_LIST.getValue(), arg);
            log.info("registerList PAY_CARD_WX_HIS apiResult:"+ JSONUtil.toJsonStr(apiResult));
//            Map dataMap = (Map) apiResult.getData();
//            if(dataMap!=null && dataMap.isEmpty()){
//                arg.put("payTypeID", BHConstants.PAY_CARD_ALI_HIS);
//                apiResult = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_OUTPATIENT_REGISTER_LIST.getValue(), arg);
//                log.info("registerList PAY_CARD_ALI_HIS apiResult:"+JSONUtil.toJsonStr(apiResult));
//            }

            if(apiResult.isError()){
                return CommonResult.error(ERROR_CODE,"生成订单失败，HIS未查询到单据信息");
            }

            //组装/解析订单信息
            Map resultMap = packageOrderInfo(apiResult,params);
            List<Map> prescriptions = (List<Map>) resultMap.get("prescriptions");
            if(prescriptions.size() <= 0){
                return CommonResult.error(ERROR_CODE,"生成订单失败，未获取到缴费单医嘱处方信息");
            }
            List<Map> prices = (List<Map>) resultMap.get("prices");
            params = (Map) resultMap.get("billMap");

            orderNumber = "JF" + RandomUtils.buildRandomStr(4);
            if("PRESCRIPTIONS_QR_CODE".equals(reqVO.getPayScene())){
                orderNumber = "QR" + RandomUtils.buildRandomStr(4);
            }
            params.put("orderNumber",orderNumber);


            outpatientMap.put("prescriptions",JSONObject.toJSONString(prescriptions));
            outpatientMap.put("prices",JSONObject.toJSONString(prices));

            totalCostB = new BigDecimal(String.valueOf(params.get("fee")));
            totalAmountB = totalCostB;
            totalCost = totalAmountB.toString();
            params.put("totalCost",totalCost);
            params.put("orderType","0");

            orderDetails.put("prescriptions",prescriptions);
            orderDetails.put("prices",prices);
        }

        outpatientMap.put("orderNumber",orderNumber);
        if(totalCostB.compareTo(totalAmountB) == 0) {
            CommonResult addBillResult = HttpUtils.postForm(getHisServerUri() + BHConstants.HIS_ADD_OUTPATIENT_BILL_ORDER.getValue(), params);
            if (addBillResult.isError()) {
                return addBillResult;
            }
            CommonResult addOutpatientResult = HttpUtils.postForm(getHisServerUri() + BHConstants.HIS_ADD_OUTPATIENT_ORDER.getValue(), outpatientMap);
            if (addOutpatientResult.isError()) {
                return addOutpatientResult;
            }

            orderDetails.put("orderName",orderName);
            orderDetails.put("billMap",params);
            orderDetails.put("orderNumber",orderNumber);
            orderDetails.put("totalCost",totalCost);
            stringRedisTemplate.opsForValue().set("OrderDetails_"+orderNumber,orderDetails.toJSONString(),30L, TimeUnit.MINUTES);

            JSONObject outpatientData = new JSONObject();
            outpatientData.put("orderNumber", orderNumber);
            return CommonResult.success(outpatientData);

        } else {
            return CommonResult.error(ERROR_CODE,"单据金额已变更，请返回首页重选待缴费单据");
        }
    }

    private Map createBillOrderParams(OutpatientCreateOrderReqVO reqVO) {

        Map params = new HashMap();
        params.put("pid",reqVO.getPId());
        params.put("userId",reqVO.getUserId());
        params.put("openid",reqVO.getOpenid());
        params.put("patientId",reqVO.getPatientId());
        params.put("patientName", reqVO.getPatientName());
        params.put("cardTypeId", BHConstants.CITY_CARD_CODE);
        params.put("cardNo", reqVO.getCardNo());
        params.put("idCardNo",reqVO.getCardNo());
        params.put("clinicNo",reqVO.getClinicNo());
        params.put("registerNo",reqVO.getRegisterNo());
        params.put("receiptNoStr",reqVO.getReceiptNoStr());
        params.put("fee",reqVO.getTotalCost());
        params.put("orderType",reqVO.getOrderType());
        params.put("address",reqVO.getAddress());


        if (BHConstants.ALIPAY_MINI_APPLET.getCode().equals(reqVO.getAppType())) {
            // 支付宝小程序
            if("chs".equals(reqVO.getPayType())) {
                params.put("payTypeID", BHConstants.PAY_CARD_ALI_CHS_CODE);
                params.put("payModeName", BHConstants.PAY_CARD_ALI_CHS_HIS);
            } else {
                params.put("payTypeID", BHConstants.PAY_CARD_ALI_CODE);
                params.put("payModeName", BHConstants.PAY_CARD_ALI_HIS);
            }
            params.put("payPlatform", BHConstants.PAY_PLATFORM_TYPE_ALI);
            params.put("payScene", BHConstants.ALIPAY_MINI_APPLET.getMsg());
        } else if(BHConstants.WEIXIN_SERVICE_ACCOUNTS.getCode().equals(reqVO.getAppType())){
            // 微信公众号
            if("chs".equals(reqVO.getPayType())) {
                // TODO 待HIS给出数据后修改
                params.put("payTypeID", BHConstants.PAY_CARD_WX_CHS_CODE);
                params.put("payModeName", BHConstants.PAY_CARD_WX_CHS_HIS);
            } else {
                params.put("payTypeID", BHConstants.PAY_CARD_WX_CODE);
                params.put("payModeName", BHConstants.PAY_CARD_WX_HIS);
            }

            params.put("payPlatform", BHConstants.PAY_PLATFORM_TYPE_WX);
            if("PRESCRIPTIONS_QR_CODE".equals(reqVO.getPayScene())){
                params.put("payScene", BHConstants.PRESCRIPTIONS_QR_CODE.getMsg());
            }else {
                params.put("payScene", BHConstants.WEIXIN_SERVICE_ACCOUNTS.getMsg());
            }
        }

        return params;
    }


    public Map packageOrderInfo(CommonResult result, Map param){
        Map billMap = param;
        String registerNo = String.valueOf(param.get("registerNo"));
        String receiptNoStr = String.valueOf(param.get("receiptNoStr"));

        BigDecimal totalCost = new BigDecimal(0);
        String orderType = "";

        Map resultMap = new HashMap();
        List<Map> prescriptions = new ArrayList<>();
        List<Map> prescriptions_prices = new ArrayList<>();
//        List<Map> mapListMXadd = new ArrayList<>();
        try {
            Map dataMap = (Map) result.getData();
            List<Map> mapList = (List<Map>) dataMap.get("GHLIST");
            for (Map ghMap : mapList) {
                //挂号就诊列表
                List<Map> ghList = (List<Map>) ghMap.get("GH");
                for (Map gh : ghList) {
                    String djh = String.valueOf(gh.get("NO"));
                    String departmentName = String.valueOf(gh.get("KDKS"));
                    String doctorId = String.valueOf(gh.get("YSID"));
                    String doctorName = String.valueOf(gh.get("YSXM"));
                    String regType = String.valueOf(gh.get("LX"));
                    String regTime = String.valueOf(gh.get("YYSJ"));

                    if(registerNo.equals(djh)){
                        List<Map> yzMapList = (List<Map>) gh.get("YZLIST");
                        for (Map yzMap : yzMapList) {
                            List<Map> yzList = (List<Map>) yzMap.get("YZ");
                            for (Map yz : yzList) {
                                HashMap<String,Object> prescription = new HashMap();
                                //单据列表
                                List<Map> mapListDJ = (List<Map>) yz.get("DJLIST");

                                boolean addFM = false;
                                if(!StringUtils.isEmpty(mapListDJ)){
                                    for (Map map : mapListDJ) {
                                        List<Map> djList = (List<Map>) map.get("DJ");
                                        for (Map dj : djList) {
                                            String djList_djh = String.valueOf(dj.get("DJH"));
                                            String zfzt = String.valueOf(dj.get("ZFZT"));

                                            boolean r = true;
                                            for (Map m : prescriptions) {
                                                String feeItemId = String.valueOf(m.get("feeItemId"));
                                                if(djList_djh.equals(feeItemId)){
                                                    r = false;
                                                    addFM = true;
                                                }
                                            }
                                            if(!r){
                                                continue;
                                            }

                                            if(receiptNoStr.contains(djList_djh) && "0".equals(zfzt)){
                                                prescription = new HashMap();
                                                prescription.put("userId",param.get("openid"));
                                                prescription.put("patientId",param.get("patientId"));
                                                prescription.put("patientName", param.get("name"));
                                                prescription.put("cardNo", param.get("cardNo"));
                                                prescription.put("idCardNo",param.get("cardNo"));
                                                prescription.put("clinicNo",param.get("clinicNo"));

                                                prescription.put("regType",regType);
                                                prescription.put("regTime",regTime);
                                                prescription.put("registerNo",djh);
                                                prescription.put("departmentName",departmentName);
                                                prescription.put("doctorId",doctorId);
                                                prescription.put("doctorName",doctorName);

                                                prescription.put("feeType",yz.get("YZLX"));
                                                prescription.put("feeId",yz.get("YZID"));
                                                prescription.put("feeItem",yz.get("YZMC"));

                                                prescription.put("feeItemId",dj.get("DJH"));
                                                prescription.put("feeItemType",dj.get("DJLX"));

                                                String je = (String) dj.get("JE");
                                                BigDecimal b = new BigDecimal(je);

                                                totalCost = totalCost.add(b);

                                                prescription.put("totalCost",dj.get("JE"));
                                                prescription.put("totalFee",dj.get("JE"));
                                                prescription.put("sumfee",dj.get("JE"));

                                                prescription.put("status",dj.get("ZFZT"));
                                                prescriptions.add(prescription);

                                                addFM = true;
                                            }
                                        }
                                    }

                                    if(addFM){
                                        List<Map> mapFMList = (List<Map>) yz.get("FMLIST");
                                        if(!StringUtils.isEmpty(mapFMList)){
                                            for (Map map : mapFMList) {
                                                List<Map> fmList = (List<Map>) map.get("FM");
                                                for (Map fm : fmList) {
                                                    List<Map> mapMxList = (List<Map>) fm.get("MXLIST");
                                                    for (Map m : mapMxList) {
                                                        prescriptions_prices.add(m);
                                                    }
                                                }
                                            }
                                        }

                                    }

                                }
                            }
                        }

                        String ghzfzt = String.valueOf(gh.get("ZFZT"));
                        if("0".equals(ghzfzt)) {
                            String ghje = String.valueOf(gh.get("JE"));
                            BigDecimal b = new BigDecimal(ghje);
                            totalCost = totalCost.add(b);

                            HashMap<String,Object> prescription = new HashMap();
                            prescription.put("userId",param.get("openid"));
                            prescription.put("patientId",param.get("patientId"));
                            prescription.put("patientName", param.get("name"));
                            prescription.put("cardNo", param.get("cardNo"));
                            prescription.put("idCardNo",param.get("cardNo"));
                            prescription.put("clinicNo",param.get("clinicNo"));

                            prescription.put("regType",regType);
                            prescription.put("regTime",regTime);
                            prescription.put("registerNo",djh);
                            prescription.put("departmentName",departmentName);
                            prescription.put("doctorId",doctorId);
                            prescription.put("doctorName",doctorName);

                            prescription.put("feeType",regType);
                            prescription.put("feeId",djh);
                            prescription.put("feeItem","挂号费");

                            prescription.put("feeItemId",djh);
                            prescription.put("feeItemType",regType);


                            prescription.put("totalCost",ghje);
                            prescription.put("totalFee",ghje);
                            prescription.put("sumfee",ghje);

                            prescription.put("status",ghzfzt);
                            prescriptions.add(prescription);
                        }
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        billMap.put("fee",totalCost.toString());
        billMap.put("orderType",orderType);

        resultMap.put("prescriptions",prescriptions);
        resultMap.put("prices",prescriptions_prices);
        resultMap.put("billMap",billMap);

        return resultMap;
    }

    public CommonResult buildPaySignData(String orderNumber) {
        Object orderObj = stringRedisTemplate.opsForValue().get("OrderDetails_" + orderNumber);
        if(orderObj == null) {
            return CommonResult.error(ErrorCodeConstants.BH_ERROR.getCode(), "订单数据不存在或已失效");
        }
        String cacheOrderData = orderObj.toString();
        JSONObject prePayInfo = JSON.parseObject(cacheOrderData);

        Map<String,Object> map = new HashMap<>();
        map.putAll(prePayInfo);
        JSONObject signDataJson = new JSONObject();
        signDataJson.put("patientId",prePayInfo.getString("patientId"));
        signDataJson.put("patientName",prePayInfo.getString("patientName"));
        signDataJson.put("clinicNo",prePayInfo.getString("clinicNo"));
        signDataJson.put("cardNo",prePayInfo.getString("cardNo"));
        signDataJson.put("pid",prePayInfo.getString("pid"));
        signDataJson.put("userId",prePayInfo.getString("userId"));
        signDataJson.put("openid",prePayInfo.getString("openid"));
        signDataJson.put("registerNo",prePayInfo.getString("registerNo"));
        signDataJson.put("orderName",prePayInfo.getString("orderName"));
        signDataJson.put("totalCost",prePayInfo.getString("totalCost"));
        signDataJson.put("orderNumber",orderNumber);

        String signData = null;
        try {
            signData = SecEncryptUtil.encryption(signDataJson.toJSONString());
        } catch (Exception e) {
            throw new ServerException(ERROR_CODE,e.getMessage());
        }
        map.put("signDataStr", signData);
        return CommonResult.success(map);
    }

    public CommonResult queryBillByOrderNumber(String orderNumber){
        Map queryMap = new HashMap();
        queryMap.put("orderNumber",orderNumber);
        CommonResult result = HttpUtils.postForm(getHisServerUri() + BHConstants.HIS_GET_OUTPATIENT_BILL_ORDER.getValue(), queryMap);

        if(result.isError()){
            return result;
        }
        Map billMap = (Map) result.getData();

        return CommonResult.success(billMap);
    }

    public CommonResult queryByOrderNumber(String orderNumber){
        Map queryMap = new HashMap();
        queryMap.put("orderNumber",orderNumber);
        CommonResult result = HttpUtils.postForm(getHisServerUri() + BHConstants.HIS_GET_OUTPATIENT_BILL_ORDER.getValue(), queryMap);

        if(result.isError()){
            return result;
        }
        Map billMap = (Map) result.getData();
        CommonResult resultItem = HttpUtils.postForm(getHisServerUri() + BHConstants.HIS_GET_OUTPATIENT_ORDER_ITEMS.getValue(), queryMap);
        if (resultItem.isSuccess()){
            billMap.put("items",resultItem.getData());
        }

        CommonResult resultPrice = HttpUtils.postForm(getHisServerUri() + BHConstants.HIS_GET_OUTPATIENT_ORDER_PRICES.getValue(), queryMap);
        if (resultPrice.isSuccess()){
            billMap.put("prices",resultPrice.getData());
        }

        return CommonResult.success(billMap);
    }

    public CommonResult payNotify(Map params){
        log.info("---------门诊缴费成功通知-------params:"+ JSONUtil.toJsonStr(params));

        String orderNumber = String.valueOf(params.get("orderNumber"));
        String thirdOrderNo = String.valueOf(params.get("thirdOrderNo"));
//        String openid = String.valueOf(params.get("openid"));
        String totalCost = String.valueOf(params.get("totalCost"));
        String payInfo = String.valueOf(params.get("payInfo"));
//        String patientName = String.valueOf(params.get("patientName"));


        CommonResult findResult = queryByOrderNumber(orderNumber);
        if(!findResult.isSuccess()) {
            return findResult;
        }
        JSONObject orderObj = (JSONObject)findResult.getData();
        if(StringUtils.hasLength(orderObj.getString("procedureStatus"))) {
            String procedureStatus = orderObj.getString("procedureStatus");
            if("success".equals(procedureStatus)) {
                return CommonResult.success("操作成功");
            }
            if("fails".equals(procedureStatus)) {
                return CommonResult.success("操作成功");
            }
        }
        String payScene = orderObj.getString("payScene");

        String orderType = orderObj.getString("orderType");

        Map paramMap = new HashMap();
        paramMap.put("hisProvider",BHConstants.HIS_PROVIDER);
        paramMap.put("partnerCompany",BHConstants.COMPANY_NAME);
        paramMap.put("tradeSerialNumber", RandomUtil.randomNumbers(9));//交易流水号
        paramMap.put("orderNumber",orderNumber);
        paramMap.put("thirdOrderNo",thirdOrderNo);
        paramMap.put("payInfo",JsonUtils.toJsonString(payInfo));

        if(BHConstants.ALIPAY_MINI_APPLET.getMsg().equals(payScene)) {
            paramMap.put("payWay", BHConstants.PAY_CARD_ALI_CODE);
        } else {
            paramMap.put("payWay", BHConstants.PAY_CARD_WX_CODE);
        }


        CommonResult payResult;
        String business = "门诊缴费";
        if("nat".equals(orderType)){
            business = "核酸检测开单";
            payResult = HttpUtils.postForm(getHisServerUri() + BHConstants.HIS_PAY_NAT_ORDER.getValue(), paramMap);
        }else {
            payResult = HttpUtils.postForm(getHisServerUri() + BHConstants.HIS_PAY_OUTPATIENT_ORDER.getValue(), paramMap);
        }
        if (payResult.isSuccess()) {

            JSONObject resultData = (JSONObject)payResult.getData();

            // TODO 推送微信模板信息
            templateMsgService.sendMsgOutpatient(orderObj);

            if(BHConstants.WEIXIN_SERVICE_ACCOUNTS.getMsg().equals(payScene) ) {
                Long pId = Long.valueOf(params.get("patientId").toString());
                // 上传数据到电子健康卡
                if(StringUtils.hasLength(getEhealthCfg().getHospitalId())) {
                    try{
                        CommonResult patientResult = patientService.findPatientById(pId);
                        JSONObject patient = (JSONObject) patientResult.getData();
                        String ehealthCardId = patient.getString("ehealthCardId");
                        if(StringUtils.hasLength(ehealthCardId)) {
                            // TODO 上传数据到电子健康卡
                            String idCard = patient.getString("cardNo");
                            String scene = "0101051";

                            ehealthService.uploadData(ehealthCardId,idCard,scene,null);

                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

            }

            // 开据电子票据
            try{
                CommonResult eReceiptResult = eInvoiceService.open(BHConstants.ORDER_TYPE_RECIPE,resultData);
                log.warn(orderNumber + "开据电子票据" + orderNumber + JsonUtils.toJsonString(eReceiptResult));
            } catch (Exception e) {
                e.printStackTrace();
                log.warn("电子票据开据失败 " + orderNumber);
            }

            // 支付宝小程序
            if(BHConstants.ALIPAY_MINI_APPLET.getMsg().equals(payScene)) {

            }

        } else {
            String message = payResult.getMsg();
            boolean b = (message.contains("交易正在进行中") || message.contains("该订单已完成"));
            if(b) {
                return CommonResult.error(ErrorCodeConstants.BH_ERROR.getCode(), message);
            }

            // 支付数据回写HIS失败
            // 推送退费审核模板消息
            refundService.saveRefundExamine(BHConstants.ORDER_TYPE_RECIPE,orderObj,message);

            return CommonResult.success(payResult.getMsg());
        }
        return CommonResult.success("");
    }


    public CommonResult seeRecord(OutpatientQueryReqVO reqVO) {
        Map params = new HashMap();
        params.put("hisProvider", BHConstants.HIS_PROVIDER);
        params.put("tradeSerialNumber",RandomUtil.randomNumbers(9));
        params.put("partnerCompany",BHConstants.COMPANY_NAME);
        params.put("patientId", reqVO.getPatientId());
        params.put("pageNow","1");
        params.put("pageSize","1");
        CommonResult result = HttpUtils.getHttp(getHisServerUri() + BHConstants.HIS_GET_OUTPATIENT_SEE_RECORD.getValue(), params);
        return result;
    }

    public CommonResult getQrcode(OutpatientQueryReqVO reqVO) {
        Map params = new HashMap();
        params.put("orderNumber", reqVO.getOrderNumber());
        CommonResult result = HttpUtils.postForm(getHisServerUri() + BHConstants.HIS_GET_OUTPATIENT_QR.getValue(), params);
        return result;
    }

}
